// 一个简单的例子
interface Person {
    name: string;
    age: number;
}
// 定义的变量属性必须为 name和age，不能多也不能少
let tom: Person = {
    name: 'tom',
    age: 18,
}

// 可选 | 只读属性
interface Animal {
    readonly name: string;
    age?: number;
}
let mike: Animal = {
    name: 'mike'
}
// mike.name = 'abc' // 无法分配到 "name" ，因为它是只读属性。

// 任意属性
/* interface PersonB {
    name: string;
    age?: number; // error 类型“number | undefined”的属性“age”不能赋给“string”索引类型“string”。
    [propName: string]: string;
} */
interface PersonB {
    name: string;
    age?: number; 
    [propName: string]: string | number | undefined;
}
let peter: PersonB = {
    name: 'peter',
    age: 10,
    gender: 'male',
    length: 100
}

// 鸭式辨形法
interface LabeledValue {
    label: string;
}
function printLabel(labeledObj: LabeledValue) {
console.log(labeledObj.label);
}
let myObj = { size: 10, label: "Size 10 Object" }
printLabel(myObj); // OK
// printLabel({ size: 10, label: "Size 10 Object" }) // error

// 绕开额外属性检查的方式
// 类型断言
interface Props { 
	name: string; 
	age: number; 
	money?: number;
}
let p: Props = {
	name: "兔神",
	age: 25,
	money: -100000,
	girl: false
} as Props; // OK

// 索引签名
interface PropsB { 
	name: string; 
	age: number; 
	money?: number;
	[key: string]: any;
}
let b: PropsB = {
	name: "兔神",
	age: 25,
	money: -100000,
	girl: false
}; // OK